home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / news / inn1.000 / inn1.4sec-linux-src.tar / inn / frontends / ctlinnd.c < prev    next >
C/C++ Source or Header  |  1993-01-29  |  8KB  |  316 lines

  1. /*  $Revision: 1.24 $
  2. **
  3. **  Send control messages to the InterNetNews daemon.
  4. */
  5. #include "configdata.h"
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. #include <errno.h>
  9. #include <sys/types.h>
  10. #include <sys/stat.h>
  11. #include "libinn.h"
  12. #include "clibrary.h"
  13. #include "inndcomm.h"
  14. #include "paths.h"
  15. #include "macros.h"
  16.  
  17.  
  18. /*
  19. **  Datatype for an entry in the command table.
  20. */
  21. typedef struct _COMMAND {
  22.     STRING    Command;
  23.     STRING    Text;
  24.     int        argc;
  25.     char    Letter;
  26.     BOOL    Glue;
  27. } COMMAND;
  28.  
  29.  
  30. STATIC COMMAND    Commands[] = {
  31.     {    "addhist",    "id arr exp post path...\tAdd history line",
  32.     5,    SC_ADDHIST,    TRUE    },
  33.     {    "allow",    "reason...\t\t\tAllow remote connections",
  34.     1,    SC_ALLOW,    TRUE    },
  35.     {    "begin",    "site\t\t\tStart newly-added site",
  36.     1,    SC_BEGIN,    FALSE    },
  37.     {    "cancel",    "id\t\t\tCancel message locally",
  38.     1,    SC_CANCEL,    FALSE    },
  39.     {    "changegroup",    "group rest\tChange mode of group",
  40.     2,    SC_CHANGEGROUP,    FALSE    },
  41.     {    "checkfile",    "\t\t\tCheck syntax of newsfeeds file",
  42.     0,    SC_CHECKFILE,    FALSE    },
  43.     {    "drop",        "site\t\t\tStop feeding site",
  44.     1,    SC_DROP,    FALSE        },
  45.     {    "flush",    "site\t\t\tFlush feed for site*",
  46.     1,    SC_FLUSH,    FALSE    },
  47.     {    "flushlogs",    "\t\t\tFlush log files",
  48.     0,    SC_FLUSHLOGS,    FALSE    },
  49.     {    "go",        "reason...\t\t\tRestart after pause or throttle",
  50.     1,    SC_GO,        TRUE    },
  51.     {    "hangup",    "channel\t\tHangup specified incoming channel",
  52.     1,    SC_HANGUP,    FALSE    },
  53.     {    "mode",        "\t\t\t\tPrint operating mode",
  54.     0,    SC_MODE,    FALSE        },
  55.     {    "name",        "nnn\t\t\tPrint name of specified channel*",
  56.     1,    SC_NAME,    FALSE        },
  57.     {    "newgroup",    "group rest creator\tCreate new group",
  58.     3,    SC_NEWGROUP,    FALSE    },
  59.     {    "param",    "letter value\t\tChange command-line parameters",
  60.     2,    SC_PARAM,    FALSE    },
  61.     {    "pause",    "reason...\t\tShort-term pause in accepting articles",
  62.     1,    SC_PAUSE,    TRUE    },
  63.     {    "readers",    "flag text...\t\tEnable or disable newsreading",
  64.     2,    SC_READERS,    TRUE    },
  65.     {    "refile",    "path group\t\tRefile an article",
  66.     2,    SC_REFILE,    FALSE    },
  67.     {    "reject",    "reason...\t\t\tReject remote connections",
  68.     1,    SC_REJECT,    TRUE    },
  69.     {    "reload",    "what reason...\t\tRe-read config files*",
  70.     2,    SC_RELOAD,    TRUE    },
  71.     {    "renumber",    "group\t\tRenumber the active file*",
  72.     1,    SC_RENUMBER,    FALSE    },
  73.     {    "reserve",    "reason...\t\tReserve the next pause or throttle",
  74.     1,    SC_RESERVE,    TRUE    },
  75.     {    "rmgroup",    "group\t\t\tRemove named group",
  76.     1,    SC_RMGROUP,    FALSE    },
  77.     {    "send",        "feed text...\t\tSend text to exploder feed",
  78.     2,    SC_SEND,    TRUE    },
  79.     {    "shutdown",    "reason...\t\tShut down server",
  80.     1,    SC_SHUTDOWN,    TRUE    },
  81.     {    "kill",    "signal site\t\tSend signal to site's process",
  82.     2,    SC_SIGNAL,    FALSE    },
  83.     {    "throttle",    "reason...\t\tStop accepting articles",
  84.     1,    SC_THROTTLE,    TRUE    },
  85.     {    "trace",    "innd|#|nnrpd flag\tTurn tracing on or off",
  86.     2,    SC_TRACE,    FALSE    },
  87.     {    "xabort",    "text...\t\tAbort the server",
  88.     1,    SC_XABORT,    TRUE    },
  89.     {    "xexec",    "path\t\t\tExec new server",
  90.     1,    SC_XEXEC,    FALSE    }
  91. };
  92.  
  93.  
  94.  
  95. /*
  96. **  Print a help summary.
  97. */
  98. STATIC NORETURN
  99. Help(p)
  100.     char        *p;
  101. {
  102.     register COMMAND    *cp;
  103.  
  104.     if (p == NULL) {
  105.     (void)printf("Command summary:\n");
  106.     for (cp = Commands; cp < ENDOF(Commands); cp++)
  107.         (void)printf("  %s %s\n", cp->Command, cp->Text);
  108.     (void)printf("*   Empty string means all sites/groups/etc.\n");
  109.     (void)printf("... All trailing words are glued together.\n");
  110.     exit(0);
  111.     }
  112.     for (cp = Commands; cp < ENDOF(Commands); cp++)
  113.     if (EQ(p, cp->Command)) {
  114.         (void)printf("Command usage:\n");
  115.         (void)printf("  %s %s\n", cp->Command, cp->Text);
  116.         exit(0);
  117.     }
  118.     (void)printf("No such command.\n");
  119.     exit(0);
  120. }
  121.  
  122.  
  123. /*
  124. **  Print a command-usage message and exit.
  125. */
  126. STATIC NORETURN
  127. WrongArgs(cp)
  128.     COMMAND    *cp;
  129. {
  130.     (void)printf("Wrong number of arguments -- usage:\n");
  131.     (void)printf("  %s %s\n", cp->Command, cp->Text);
  132.     exit(1);
  133. }
  134.  
  135.  
  136. /*
  137. **  Print an error message and exit.
  138. */
  139. STATIC NORETURN
  140. Failed(p)
  141.     char    *p;
  142. {
  143.     if (ICCfailure)
  144.     (void)fprintf(stderr, "Can't %s (%s failure) %s.\n",
  145.         p, ICCfailure, strerror(errno));
  146.     else
  147.     (void)fprintf(stderr, "Can't %s, %s.\n", p, strerror(errno));
  148.     (void)ICCclose();
  149.     exit(1);
  150. }
  151.  
  152.  
  153. /*
  154. **  Print an error reporting incorrect usage.
  155. */
  156. STATIC NORETURN
  157. Usage(what)
  158.     char    *what;
  159. {
  160.     (void)fprintf(stderr, "Usage error (%s) -- try -h for help.\n", what);
  161.     exit(1);
  162. }
  163.  
  164.  
  165. int
  166. main(ac, av)
  167.     int            ac;
  168.     char        *av[];
  169. {
  170.     static char        Y[] = "y";
  171.     static char        EMPTY[] = "";
  172.     register COMMAND    *cp;
  173.     register char    *p;
  174.     register int    i;
  175.     BOOL        Silent;
  176.     BOOL        NeedHelp;
  177.     char        *reply;
  178.     char        *new;
  179.     int            length;
  180.     char        *nv[4];
  181.     struct stat        Sb;
  182.     char        buff[SMBUF];
  183.  
  184.     /* Set defaults. */
  185.     Silent = FALSE;
  186.     NeedHelp = FALSE;
  187.     ICCsettimeout(CTLINND_TIMEOUT);
  188.  
  189.     /* Parse JCL. */
  190.     while ((i = getopt(ac, av, "hst:")) != EOF)
  191.     switch (i) {
  192.     default:
  193.         Usage("bad flags");
  194.         /* NOTREACHED */
  195.     case 'h':        /* Get help            */
  196.         NeedHelp = TRUE;
  197.         break;
  198.     case 's':        /* Silent -- no output        */
  199.         Silent = TRUE;
  200.         break;
  201.     case 't':        /* Time to wait for reply    */
  202.         ICCsettimeout(atoi(optarg));
  203.         break;
  204.     }
  205.     ac -= optind;
  206.     av += optind;
  207.     if (NeedHelp)
  208.     Help(av[0]);
  209.     if (ac == 0)
  210.     Usage("missing command");
  211.  
  212.     /* Look up the command word and move to the arguments. */
  213.     if (EQ(av[0], "help"))
  214.     Help(av[1]);
  215.     for (cp = Commands; cp < ENDOF(Commands); cp++)
  216.     if (EQ(av[0], cp->Command))
  217.         break;
  218.     if (cp == ENDOF(Commands))
  219.     Usage("unknown command");
  220.     ac--;
  221.     av++;
  222.  
  223.     /* Check argument count. */
  224.     if (cp->Letter == SC_NEWGROUP) {
  225.     /* Newgroup command has defaults. */
  226.     switch (ac) {
  227.     default:
  228.         WrongArgs(cp);
  229.         /* NOTREACHED */
  230.     case 1:
  231.         nv[0] = av[0];
  232.         nv[1] = Y;
  233.         nv[2] = EMPTY;
  234.         nv[3] = NULL;
  235.         av = nv;
  236.         break;
  237.     case 2:
  238.         nv[0] = av[0];
  239.         nv[1] = av[1];
  240.         nv[2] = EMPTY;
  241.         nv[3] = NULL;
  242.         av = nv;
  243.         break;
  244.     case 3:
  245.         break;
  246.     }
  247.     switch (av[1][0]) {
  248.     default:
  249.         Usage("Bad group mode");
  250.         /* NOTREACHED */
  251.     case NF_FLAG_ALIAS:
  252.     case NF_FLAG_EXCLUDED:
  253.     case NF_FLAG_MODERATED:
  254.     case NF_FLAG_OK:
  255.     case NF_FLAG_NOLOCAL:
  256.     case NF_FLAG_IGNORE:
  257.         break;
  258.     }
  259.     ac = 3;
  260.     }
  261.     else if (ac > cp->argc && cp->Glue) {
  262.     /* Glue any extra words together. */
  263.     for (length = 0, i = cp->argc - 1; (p = av[i++]) != NULL; )
  264.         length += strlen(p) + 1;
  265.     for (new = p = NEW(char, length), i = cp->argc - 1; av[i]; i++) {
  266.         if (i >= cp->argc)
  267.         *p++ = ' ';
  268.         p += strlen(strcpy(p, av[i]));
  269.     }
  270.     av[cp->argc - 1] = new;
  271.     av[cp->argc] = NULL;
  272.     }
  273.     else if (ac != cp->argc)
  274.     /* All other commands must have the right number of arguments. */
  275.     WrongArgs(cp);
  276.  
  277.     /* Make sure there are no separators in the parameters. */
  278.     for (i = 0; (p = av[i++]) != NULL; )
  279.     if (strchr(p, SC_SEP) != NULL) {
  280.         (void)fprintf(stderr, "Illegal character '\\%03o' in \"%s\"\n",
  281.             SC_SEP, p);
  282.         exit(1);
  283.     }
  284.  
  285.     /* Do the real work. */
  286.     if (ICCopen() < 0)
  287.     Failed("setup communication");
  288.     i = ICCcommand(cp->Letter, av, &reply);
  289.     if (i < 0) {
  290.     i = errno;
  291.     if (stat(_PATH_SERVERPID, &Sb) < 0)
  292.         (void)fprintf(stderr, "No innd.pid file; did server die?\n");
  293.     (void)sprintf(buff, "send \"%s\" command", cp->Command);
  294.     errno = i;
  295.     Failed(buff);
  296.     }
  297.  
  298.     if (reply) {
  299.     /* Skip "<exitcode><space>" part of reply. */
  300.     for (p = reply; *p && CTYPE(isdigit, *p); p++)
  301.         continue;
  302.     while (*p && ISWHITE(*p))
  303.         p++;
  304.     if (i != 0)
  305.         (void)fprintf(stderr, "%s\n", p);
  306.     else if (!Silent)
  307.         (void)printf("%s\n", p);
  308.     }
  309.  
  310.     if (ICCclose() < 0)
  311.     Failed("end communication");
  312.  
  313.     exit(i);
  314.     /* NOTREACHED */
  315. }
  316.